package io.github.zhx666666.word;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.parser.Feature;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.util.ZipSecureFile;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @Author: zhaohaoxin
 * @Date: 2023-10-10-15:22
 */
public class WordCreateUtil {


    static {
        ZipSecureFile.setMinInflateRatio(-1.0d);
    }
    public static void main(String[] args) {
        //String urlDb = WordCreateUtil.wordFileMerging("/Users/mac/download-file/jar-logs/dras/website/dras_pc/drasFile/report/word/20231129/161739_XXXXXX报告（拷贝）-生成稿20231129.docx", "/Users/mac/download-file/jar-logs/dras/website/dras_pc/drasFile/report/word/20231129/d537803808ce41faacbf9cfff708992b55.docx", "体系数据", "/Users/mac/download-file/jar-logs/dras/website/dras_pc/drasFile/report/word");
        String a ="/Users/mac/download-file/jar-logs/dras/website/dras_pc/drasFile/report/word/20231129/161739_XXXXXX报告（拷贝）-生成稿20231129.docx";
        String b ="/Users/mac/download-file/jar-logs/dras/website/dras_pc/drasFile/report/word/20231129/d537803808ce41faacbf9cfff708992b55.docx";
        String urlDb = WordCreateUtil.wordFileMerging2(a, b, "（一）水安全", "/Users/mac/download-file/jar-logs/dras/website/dras_pc/drasFile/report/word");
        System.out.println(urlDb);
    }
    public static String wordFileMerging(String targetFilePath,String sourceFilePath,String targetTitle,String path){
        try {
            FileInputStream targetFileStream = new FileInputStream(targetFilePath);
            XWPFDocument targetDocument = new XWPFDocument(targetFileStream);
            targetFileStream.close();

            FileInputStream sourceFileStream = new FileInputStream(sourceFilePath);
            XWPFDocument sourceDocument = new XWPFDocument(sourceFileStream);
            sourceFileStream.close();





            // 在这里添加逻辑以找到目标标题
            boolean foundTargetTitle = false;
            // 复制段落和样式
            // 复制段落和样式
            for (XWPFParagraph paragraph : sourceDocument.getParagraphs()) {
                if (!foundTargetTitle) {
                    if (paragraph.getText().contains(targetTitle)) {
                        foundTargetTitle = true;
                    }
                    XWPFParagraph newParagraph = targetDocument.createParagraph();
                    newParagraph.getCTP().setPPr(paragraph.getCTP().getPPr());



                    for (XWPFRun run : paragraph.getRuns()) {
                        XWPFRun newRun = newParagraph.createRun();
                        newRun.getCTR().setRPr(run.getCTR().getRPr());
                        //复制段落
                        newRun.setText(run.text());


                        // 复制段落中的图片

                        for (XWPFPicture picture : run.getEmbeddedPictures()) {
                            XWPFPictureData pictureData = picture.getPictureData();
                            //byte[] pictureBytes = pictureData.getData();
                            //int pictureType = pictureData.getPackagePart().getContentType().getPackagePart().getPackage().getContentType();
                            int pictureType = pictureData.getPictureType();//pictureData.getPackagePart().getContentType().getPackagePart().getPackage().getContentType();
                            InputStream inputStream = picture.getPictureData().getPackagePart().getInputStream();
                            //获取文件属行
                            long width = 0;
                            long height = 0;



                            // 获取图片的尺寸信息
                            CTPositiveSize2D extent = picture.getCTPicture().getSpPr().getXfrm().getExt();

                            if (extent != null) {
                                width = extent.getCx();
                                height = extent.getCy();

                                // 如果需要将尺寸从英寸（1/360000）转换为磅（1/20）
//                                width = (long) (Units.toPoints(width) / 20);
//                                height = (long) (Units.toPoints(height) / 20);
                            }

                            // 在目标文档中创建新的图片对象
                            try {
                                XWPFPicture newPicture = newParagraph.createRun().addPicture(
                                        inputStream, pictureType, pictureData.getFileName(), Units.toEMU(Units.toPoints(width)), Units.toEMU(Units.toPoints(height))
                                );
                            } catch (InvalidFormatException e) {
                                throw new RuntimeException(e);
                            }
                        }

                    }
                }
            }




            // 复制表格
            for (XWPFTable table : sourceDocument.getTables()) {
                // 创建新的表格
                XWPFTable newTable = targetDocument.createTable();

                // 复制表格属性
                newTable.getCTTbl().setTblPr(table.getCTTbl().getTblPr());

                // 复制表格行和单元格
                for (XWPFTableRow row : table.getRows()) {
                    XWPFTableRow newRow = newTable.createRow();

                    // 复制行属性
                    newRow.getCtRow().setTrPr(row.getCtRow().getTrPr());

                    // 复制单元格和内容
                    for (int i = 0; i < row.getTableCells().size(); i++) {
                        XWPFTableCell sourceCell = row.getCell(i);
                        XWPFTableCell newCell = (i < newRow.getTableCells().size()) ? newRow.getCell(i) : newRow.createCell();
                        CTTc ctTc = newCell.getCTTc();
                        // 复制单元格属性
                        ctTc.setTcPr(sourceCell.getCTTc().getTcPr());

                        // 复制单元格内容
                        for (XWPFParagraph paragraph2 : sourceCell.getParagraphs()) {
                            XWPFParagraph newParagraph = newCell.addParagraph();
                            newParagraph.getCTP().setPPr(paragraph2.getCTP().getPPr());

                            for (XWPFRun run : paragraph2.getRuns()) {
                                XWPFRun newRun = newParagraph.createRun();
                                newRun.getCTR().setRPr(run.getCTR().getRPr());
                                newRun.setText(run.text());
                            }
                        }

                        // 复制单元格中的图片（如果有）
//                        for (XWPFPicture picture : sourceCell.getParagraphs().get(0).getRuns().get(0).getEmbeddedPictures()) {
//                            // 处理图片复制逻辑
//                            // 请根据之前的图片复制逻辑进行处理
//                        }
                    }
                }
            }







            // 创建临时目录
            //String tmpdirPath = System.getProperty("java.io.tmpdir");
            String dateStr = new SimpleDateFormat("yyyyMMdd").format(new Date());
            String dateStr2 = new SimpleDateFormat("HHmmss").format(new Date());

            String fileName = dateStr2+"_"+ UUID.randomUUID().toString().replace("-", "") + ".docx";
            //String uuId = UUID.randomUUID().toString().replaceAll("-", "");
            String[] params = {path, dateStr,fileName};
            String[] params2 = {path, dateStr};
            String fileUrl2 = StringUtils.join( params2, File.separator);
            if (!new File(fileUrl2).exists()) {
                new File(fileUrl2).mkdirs();
            }
            // 结果例如：C:\Users\Administrator\AppData\Local\Temp\20220630\0f774122c38b423793cc1c121611c142
            String fileUrl = StringUtils.join( params, "/");

            // 保存合并后的文档
            FileOutputStream mergedFileStream = new FileOutputStream(fileUrl);
            targetDocument.write(mergedFileStream);
            mergedFileStream.close();
            return fileUrl;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    public static String wordFileMerging2(String targetFilePath, String sourceFilePath, String targetTitle, String path) {
        try {
            FileInputStream targetFileStream = new FileInputStream(targetFilePath);
            XWPFDocument targetDocument = new XWPFDocument(targetFileStream);
            targetFileStream.close();

            FileInputStream sourceFileStream = new FileInputStream(sourceFilePath);
            XWPFDocument sourceDocument = new XWPFDocument(sourceFileStream);
            sourceFileStream.close();

            boolean foundTargetTitle = false;

            for (XWPFParagraph paragraph : targetDocument.getParagraphs()) {
                if (paragraph.getText().contains(targetTitle)) {
                    foundTargetTitle = true;
                    System.out.println(paragraph.getText());
                    // 在目标标题段落之后创建新段落并插入源文件内容（段落、表格等）
                    XWPFParagraph newParagraph = targetDocument.createParagraph();

                    for (IBodyElement element : sourceDocument.getBodyElements()) {
                        if (element instanceof XWPFParagraph) {
                            XWPFParagraph sourceParagraph = (XWPFParagraph) element;
                            newParagraph.getCTP().setPPr(sourceParagraph.getCTP().getPPr());

                            for (XWPFRun run : sourceParagraph.getRuns()) {
                                XWPFRun newRun = newParagraph.createRun();
                                newRun.getCTR().setRPr(run.getCTR().getRPr());
                                newRun.setText(run.text());
                            }
                        } else if (element instanceof XWPFTable) {
                            XWPFTable sourceTable = (XWPFTable) element;
                            XWPFTable newTable = targetDocument.createTable();
                            newTable.getCTTbl().setTblPr(sourceTable.getCTTbl().getTblPr());

                            for (XWPFTableRow row : sourceTable.getRows()) {
                                XWPFTableRow newRow = newTable.createRow();
                                newRow.getCtRow().setTrPr(row.getCtRow().getTrPr());

                                for (int i = 0; i < row.getTableCells().size(); i++) {
                                    XWPFTableCell sourceCell = row.getCell(i);
                                    XWPFTableCell newCell = (i < newRow.getTableCells().size()) ? newRow.getCell(i) : newRow.createCell();
                                    newCell.getCTTc().setTcPr(sourceCell.getCTTc().getTcPr());

                                    for (XWPFParagraph cellParagraph : sourceCell.getParagraphs()) {
                                        XWPFParagraph newCellParagraph = newCell.addParagraph();
                                        newCellParagraph.getCTP().setPPr(cellParagraph.getCTP().getPPr());

                                        for (XWPFRun run : cellParagraph.getRuns()) {
                                            XWPFRun newRun = newCellParagraph.createRun();
                                            newRun.getCTR().setRPr(run.getCTR().getRPr());
                                            newRun.setText(run.text());
                                        }
                                    }
                                }
                            }
                        }
                    }
                    break; // 找到目标标题后结束循环
                }
            }

            // ... （保存合并后的文档到指定目录下的逻辑）

            // 创建临时目录
            //String tmpdirPath = System.getProperty("java.io.tmpdir");
            String dateStr = new SimpleDateFormat("yyyyMMdd").format(new Date());
            String dateStr2 = new SimpleDateFormat("HHmmss").format(new Date());

            String fileName = dateStr2+"_"+ UUID.randomUUID().toString().replace("-", "") + ".docx";
            //String uuId = UUID.randomUUID().toString().replaceAll("-", "");
            String[] params = {path, dateStr,fileName};
            String[] params2 = {path, dateStr};
            String fileUrl2 = StringUtils.join( params2, File.separator);
            if (!new File(fileUrl2).exists()) {
                new File(fileUrl2).mkdirs();
            }
            // 结果例如：C:\Users\Administrator\AppData\Local\Temp\20220630\0f774122c38b423793cc1c121611c142
            String fileUrl = StringUtils.join( params, "/");

            // 保存合并后的文档
            FileOutputStream mergedFileStream = new FileOutputStream(fileUrl);
            targetDocument.write(mergedFileStream);
            mergedFileStream.close();
            return fileUrl;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }




    public static String createWord(String str,String path,String fileName,String parentId) {




        List<TreeView> viewList = JSONObject.parseObject(str, new TypeReference<List<TreeView>>() {
        }, Feature.OrderedField);

        // 组装目录树，每个目录里面放置的是富文本，其中富文本存在于directoryBody字段中，目录名称存在于directoryName字段中，然后组装出来的目录结构树如下图
        List<TreeView> treeList = createTreeViewTree(parentId, viewList);


        try {

            // 创建空的word文档作为导出位置，其中word文档名称是“坦克.docx”

            // 参数判断
            if (StringUtils.isBlank(fileName)) {
                return null;
            }
            // 创建临时目录
            //String tmpdirPath = System.getProperty("java.io.tmpdir");
            String dateStr = new SimpleDateFormat("yyyyMMdd").format(new Date());
            String dateStr2 = new SimpleDateFormat("HHmmss").format(new Date());
            fileName = dateStr2+"_"+fileName + ".docx";
            //String uuId = UUID.randomUUID().toString().replaceAll("-", "");
            String[] params = {path, dateStr};
            // 结果例如：C:\Users\Administrator\AppData\Local\Temp\20220630\0f774122c38b423793cc1c121611c142
            String fileUrl = StringUtils.join( params, File.separator);
            if (!new File(fileUrl).exists()) {
                new File(fileUrl).mkdirs();
            }
            // 创建临时文件
            File file = new File(fileUrl, fileName);
            file.createNewFile();


            // 第二个参数为true代表开启公文格式
            XWPFDocument document = getXWPFDocument(treeList, true);
            WordUtil.generateDocxFile(document, file);
            return path+dateStr+"/"+fileName;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;

    }

    /**
     * 创建目录树
     *
     * @param
     * @return
     * @author 明快de玄米61
     * @date 2022/10/12 0:02
     **/
    private static List<TreeView> createTreeViewTree(String parentId, List<TreeView> viewList) {
        List<TreeView> treeList = new ArrayList<TreeView>();

        for (TreeView view : viewList) {
            if (parentId.equals(view.getParentId())) {
                view.setChildren(createTreeViewTree(view.getId(), viewList));
                treeList.add(view);
            }
        }
        return treeList;
    }

    /**
     * 获取XWPFDocument
     *
     * @param treeList    目录树
     * @param odfDealFlag 是否开启公文格式
     * @return
     * @author 明快de玄米61
     * @date 2022/10/12 0:01
     **/
    public static XWPFDocument getXWPFDocument(List<TreeView> treeList, boolean odfDealFlag) {
        // 初始化XWPFDocument
        XWPFDocument document = WordUtil.initXWPFDocument();

        // 组装模板目录列表
        dealDirectoryViewTree(document, treeList, odfDealFlag);

        return document;
    }

    private static void dealDirectoryViewTree(XWPFDocument document, List<TreeView> treeList, boolean odfDealFlag) {
        for (int i = 0; i < treeList.size(); i++) {
            TreeView view = treeList.get(i);
            String directoryName = view.getDirectoryName();
            Integer type = view.getType();
            if (StringUtils.isEmpty(directoryName)) {
                directoryName = " ";
            }

            // 处理中间大标题
            if (type == 0) {
                WordUtil.dealDocxTitle(document, directoryName);
            }
            // 处理正文标题
            else {
                WordUtil.dealHeading(document, type, i + 1, directoryName, odfDealFlag);
            }

            // 处理正文
            WordUtil.dealHtmlContent(document, view.getDirectoryBody());

            // 处理子级列表
            if (view.getChildren() != null && view.getChildren().size() > 0) {
                dealDirectoryViewTree(document, view.getChildren(), odfDealFlag);
            }
        }
    }
}

class TreeView implements Serializable {

    private static final long serialVersionUID = 1L;

    // 分类id
    private String id;

    // 目录名称
    private String directoryName;

    // 目录详情
    private String directoryBody;

    // 目录详情数据
    private String bodyData;

    // 父节点id
    private String parentId;


    // 节点类型
    private Integer type;


    // 排序号
    private Integer seq;

    // 句子
    private String sentences;

    // 关系图数据
    private String statisticalBody;

    // 子级集合
    private List<TreeView> children;


    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getDirectoryName() {
        return directoryName;
    }

    public void setDirectoryName(String directoryName) {
        this.directoryName = directoryName;
    }

    public String getDirectoryBody() {
        return directoryBody;
    }

    public void setDirectoryBody(String directoryBody) {
        this.directoryBody = directoryBody;
    }

    public String getBodyData() {
        return bodyData;
    }

    public void setBodyData(String bodyData) {
        this.bodyData = bodyData;
    }

    public String getParentId() {
        return parentId;
    }

    public void setParentId(String parentId) {
        this.parentId = parentId;
    }

    public Integer getType() {
        return type;
    }

    public void setType(Integer type) {
        this.type = type;
    }

    public Integer getSeq() {
        return seq;
    }

    public void setSeq(Integer seq) {
        this.seq = seq;
    }

    public String getSentences() {
        return sentences;
    }

    public void setSentences(String sentences) {
        this.sentences = sentences;
    }

    public String getStatisticalBody() {
        return statisticalBody;
    }

    public void setStatisticalBody(String statisticalBody) {
        this.statisticalBody = statisticalBody;
    }

    public List<TreeView> getChildren() {
        return children;
    }

    public void setChildren(List<TreeView> children) {
        this.children = children;
    }
}
